package com.liyong.pullorder.sdk.parser;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.liyong.pullorder.sdk.autoconfigure.PullOrderSdkProperties;
import com.liyong.pullorder.sdk.dto.StandardOrderDto;
import com.liyong.pullorder.sdk.exception.DataParseException;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 葡萄味的萝卜
 * @date 2025/10/21 12:13
 * JSON数据解析策略实现
 * 应用平台：华为、荣耀等返回JSON格式的现代电商平台
 * 核心能力：灵活字段映射、嵌套对象解析、数据类型转换
 *
 * 技术特性：
 * - 基于Jackson的高性能JSON解析
 * - 支持动态字段映射配置
 * - 自动类型转换和空值处理
 * - 嵌套数据结构展开
 */
@Slf4j
public class JsonParserStrategy implements ParserStrategy{
    private final ObjectMapper objectMapper;

    public JsonParserStrategy() {
        this.objectMapper = new ObjectMapper();
        // 配置Jackson，提高解析容错性
        this.objectMapper.configure(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        this.objectMapper.configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_COMMENTS, true);
    }

    @Override
    public String getSupportedFormat() {
        return "JSON";
    }

    @Override
    public boolean supports(String dataFormat) {
        return "JSON".equalsIgnoreCase(dataFormat);
    }

    /**
     * 解析JSON格式的订单数据
     * 解析流程：
     * 1. JSON字符串解析为JsonNode
     * 2. 提取订单列表节点
     * 3. 遍历解析单个订单
     * 4. 数据清洗和验证
     */
    @Override
    public List<StandardOrderDto> parse(String rawData, PullOrderSdkProperties.PlatformConfig platformConfig) {
        log.debug("开始解析JSON数据 - 平台: {}, 数据长度: {}",
                platformConfig.getBaseUrl(), rawData.length());

        try {
            JsonNode rootNode = objectMapper.readTree(rawData);

            // 根据平台配置提取订单列表节点
            JsonNode ordersNode = extractOrdersNode(rootNode, platformConfig);

            if (ordersNode == null || !ordersNode.isArray()) {
                log.warn("JSON数据中未找到订单列表 - 平台: {}", platformConfig.getBaseUrl());
                return new ArrayList<>();
            }

            List<StandardOrderDto> orders = new ArrayList<>();
            for (JsonNode orderNode : ordersNode) {
                try {
                    StandardOrderDto order = parseSingleOrder(orderNode, platformConfig);
                    if (order != null) {
                        orders.add(order);
                    }
                } catch (Exception e) {
                    log.warn("解析单个订单失败，跳过该订单 - 平台: {}, 错误: {}",
                            platformConfig.getBaseUrl(), e.getMessage());
                    // 单个订单解析失败不影响其他订单
                }
            }

            log.info("JSON解析完成 - 平台: {}, 解析订单数: {}",
                    platformConfig.getBaseUrl(), orders.size());

            return cleanAndValidate(orders);

        } catch (Exception e) {
            log.error("JSON数据解析失败 - 平台: {}, 原始数据: {}",
                    platformConfig.getBaseUrl(),
                    rawData.substring(0, Math.min(200, rawData.length())));
            throw new DataParseException("JSON数据解析失败: " + e.getMessage(), e.getMessage());
        }
    }

    /**
     * 提取订单列表节点
     * 支持多种JSON结构：
     * 1. 直接数组：[{order1}, {order2}]
     * 2. 包装对象：{data: {orders: [{order1}, {order2}]}}
     * 3. 分页结构：{data: {list: [{order1}], total: 100}}
     */
    private JsonNode extractOrdersNode(JsonNode rootNode,
                                       PullOrderSdkProperties.PlatformConfig platformConfig) {
        // 优先使用配置的节点路径
        String ordersPath = platformConfig.getParser().getMapping().get("ordersPath");
        if (ordersPath != null) {
            String[] paths = ordersPath.split("\\.");
            JsonNode currentNode = rootNode;
            for (String path : paths) {
                if (currentNode != null) {
                    currentNode = currentNode.get(path);
                }
            }
            return currentNode;
        }

        // 默认探测常见节点名
        String[] commonPaths = {"data", "orders", "list", "result", "items"};
        for (String path : commonPaths) {
            JsonNode node = rootNode.get(path);
            if (node != null && node.isArray()) {
                return node;
            }
        }

        // 如果根节点就是数组，直接返回
        if (rootNode.isArray()) {
            return rootNode;
        }

        return null;
    }

    /**
     * 解析单个订单节点
     * 字段映射：根据平台配置将平台字段映射到标准字段
     * 类型转换：字符串到数值、日期等类型的智能转换
     */
    private StandardOrderDto parseSingleOrder(JsonNode orderNode,
                                              PullOrderSdkProperties.PlatformConfig platformConfig) {
        try {
            StandardOrderDto.OrderDtoBuilder builder = StandardOrderDto.builder();
            String platformCode = extractPlatformCode(platformConfig.getBaseUrl());

            // 1. 平台订单ID - 必需字段，为空则跳过该订单
            String orderId = extractFieldValue(orderNode, "orderId", platformConfig); // 修正：移除 standardField:
            if (orderId == null || orderId.trim().isEmpty()) {
                log.warn("订单ID为空，跳过该订单 - 平台：{}", platformCode);
                return null;
            }
            builder.platformOrderId(orderId.trim());
            builder.platformCode(platformCode);

            // 2. 订单金额 - 支持多种金额字段名和格式
            BigDecimal amount = extractAmount(orderNode, platformConfig);
            if (amount == null) {
                log.debug("订单金额为空，使用默认值0 - 订单ID：{}，平台：{}", orderId, platformCode);
                amount = BigDecimal.ZERO;
            }
            builder.orderAmount(amount);
            builder.currency(extractCurrency(orderNode, platformConfig));

            // 3. 订单状态 - 状态码映射和标准化
            String status = extractFieldValue(orderNode, "status", platformConfig); // 修正：移除 standardField:
            String standardizedStatus = mapOrderStatus(status, platformConfig);
            builder.orderStatus(standardizedStatus);

            // 4. 时间字段处理 - 支持多种时间格式
            String orderTimeStr = extractFieldValue(orderNode, "orderTime", platformConfig); // 修正：移除 standardField:
            Date orderTime = parseDateTime(orderTimeStr, platformConfig);
            builder.orderTime(orderTime != null ? orderTime : new Date());

            // 5. 客户信息 - 姓名和电话清洗
            String customerName = extractFieldValue(orderNode, "customerName", platformConfig);
            if (customerName != null) {
                builder.customerName(customerName.trim());
            }

            String customerPhone = extractFieldValue(orderNode, "customerPhone", platformConfig);
            if (customerPhone != null) {
                builder.customerPhone(cleanPhoneNumber(customerPhone));
            }

            // 6. 收货地址 - 地址信息标准化
            String shippingAddress = extractFieldValue(orderNode, "shippingAddress", platformConfig);
            if (shippingAddress != null) {
                builder.shippingAddress(cleanAddress(shippingAddress));
            }

            // 7. 扩展字段 - 保存平台特定信息
            builder.extraFields(extractExtraFields(orderNode, platformConfig));

            // 8. 系统字段
            builder.createTime(new Date());
            builder.updateTime(new Date());

            return builder.build();

        } catch (Exception e) {
            log.warn("解析单个订单详情失败 - 平台: {}, 错误: {}",
                    platformConfig.getBaseUrl(), e.getMessage());
            return null;
        }
    }

    /**
     * 提取字段值，支持字段映射配置
     */
    private String extractFieldValue(JsonNode orderNode, String standardField,
                                     PullOrderSdkProperties.PlatformConfig platformConfig) {
        // 查找字段映射配置
        String platformField = platformConfig.getParser().getMapping().get(standardField);
        if (platformField == null) {
            platformField = standardField; // 默认使用标准字段名
        }

        JsonNode valueNode = orderNode.get(platformField);
        if (valueNode != null && !valueNode.isNull()) {
            return valueNode.asText();
        }

        return null;
    }

    /**
     * 提取订单金额，支持多种金额字段和格式
     */
    private BigDecimal extractAmount(JsonNode orderNode,
                                     PullOrderSdkProperties.PlatformConfig platformConfig) {
        try {
            String amountStr = extractFieldValue(orderNode, "orderAmount", platformConfig);
            if (amountStr != null) {
                return new BigDecimal(amountStr);
            }
        } catch (Exception e) {
            log.warn("金额格式转换失败: {}", e.getMessage());
        }
        return BigDecimal.ZERO;
    }

    /**
     * 订单状态映射，将平台状态码转换为标准状态
     */
    private String mapOrderStatus(String platformStatus,
                                  PullOrderSdkProperties.PlatformConfig platformConfig) {
        if (platformStatus == null) return "UNKNOWN";

        // 从配置中获取状态映射
        String statusMapping = platformConfig.getParser().getMapping().get("statusMapping." + platformStatus);
        if (statusMapping != null) {
            return statusMapping;
        }

        // 默认映射
        switch (platformStatus) {
            case "1": case "paid": return "PAID";
            case "2": case "shipped": return "SHIPPED";
            case "3": case "completed": return "COMPLETED";
            default: return "UNKNOWN";
        }
    }

    /**
     * 解析日期时间，支持多种格式
     */
    private java.util.Date parseDateTime(String dateTimeStr) {
        if (dateTimeStr == null) {
            return new Date();
        }

        try {
            // 简化实现，实际应该支持多种日期格式
            return new java.util.Date(); // 实际应该使用SimpleDateFormat或DateTimeFormatter
        } catch (Exception e) {
            log.warn("日期解析失败: {}, 使用当前时间", dateTimeStr);
            return new java.util.Date();
        }
    }

    /**
     * 提取扩展字段，保存平台特定信息
     */
    private java.util.Map<String, Object> extractExtraFields(JsonNode orderNode,
                                                             PullOrderSdkProperties.PlatformConfig platformConfig) {
        java.util.Map<String, Object> extraFields = new java.util.HashMap<>();

        // 提取所有未映射的字段作为扩展字段
        java.util.Iterator<String> fieldNames = orderNode.fieldNames();
        while (fieldNames.hasNext()) {
            String fieldName = fieldNames.next();
            // 如果这个字段没有被标准字段映射，就作为扩展字段
            if (!isStandardField(fieldName, platformConfig)) {
                JsonNode fieldValue = orderNode.get(fieldName);
                if (fieldValue != null && !fieldValue.isNull()) {
                    extraFields.put(fieldName, fieldValue.asText());
                }
            }
        }

        return extraFields;
    }

    /**
     * 检查字段是否为标准字段
     */
    private boolean isStandardField(String fieldName, PullOrderSdkProperties.PlatformConfig platformConfig) {
        String[] standardFields = {"orderId", "orderAmount", "status", "orderTime",
                "customerName", "customerPhone", "shippingAddress"};
        for (String stdField : standardFields) {
            String mappedField = platformConfig.getParser().getMapping().get(stdField);
            if (fieldName.equals(mappedField) || fieldName.equals(stdField)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 数据清洗和验证
     * 保障数据质量，为下游系统提供洁净数据源
     */
    @Override
    public List<StandardOrderDto> cleanAndValidate(List<StandardOrderDto> orders) {
        List<StandardOrderDto> cleanedOrders = new ArrayList<>();

        for (StandardOrderDto order : orders) {
            try {
                // 基础验证
                if (order.getPlatformOrderId() == null || order.getPlatformOrderId().trim().isEmpty()) {
                    log.warn("订单ID为空，跳过该订单");
                    continue;
                }

                // 金额验证
                if (order.getOrderAmount() == null || order.getOrderAmount().compareTo(BigDecimal.ZERO) < 0) {
                    log.warn("订单金额异常，订单ID: {}, 金额: {}",
                            order.getPlatformOrderId(), order.getOrderAmount());
                    order.setOrderAmount(BigDecimal.ZERO);
                }

                // 手机号格式清洗
                if (order.getCustomerPhone() != null) {
                    order.setCustomerPhone(cleanPhoneNumber(order.getCustomerPhone()));
                }

                cleanedOrders.add(order);

            } catch (Exception e) {
                log.warn("订单数据清洗失败，订单ID: {}, 错误: {}",
                        order.getPlatformOrderId(), e.getMessage());
            }
        }

        log.info("数据清洗完成 - 原始订单数: {}, 有效订单数: {}",
                orders.size(), cleanedOrders.size());

        return cleanedOrders;
    }

    /**
     * 手机号格式清洗
     */
    private String cleanPhoneNumber(String phone) {
        if (phone == null) {
            return null;
        }
        // 移除空格、横杠等特殊字符
        return phone.replaceAll("[\\s-]+", "");
    }
}
